/***************************************************************
|	File:		GameplayState.h
|	Author:		John Gawne
|	Course:		Structure of Game Design
|	Purpose:	GameplayState class initializes & runs the game logic
***************************************************************/

#ifndef GAMEPLAYSTATE_H
#define GAMEPLAYSTATE_H


#include "IGameState.h"						// uses IGameState
#include "../SGD Wrappers/SGD_Handle.h"		// uses HTexture & HAudio

#include "TileSystem.h"
/**************************************************************/
// Forward class declaration
//	- tells the compiler that the type exists
//	- allows us to create pointers or references
//class BaseObject;
class ObjectManager;
class Explosion;
class Crosshair;
class Camera;
class Crate;
class BitmapFont;
class Bomb;
#include "../SGD Wrappers/SGD_Declarations.h"

#include <map>
#include "../SGD Wrappers/SGD_String.h"


/**************************************************************/
// GameplayState class
//	- runs the game logic
//	- SINGLETON! (Static allocation, not dynamic)
class Player;
class StaticObject;

class GameplayState : public IGameState
{
public:
	/**********************************************************/
	// Singleton Accessor:
	static GameplayState* GetInstance( void );

	/**********************************************************/
	// Screen Size Accessors:
	float	GetScreenWidth	( void ) const	{	return m_fScreenWidth;	}
	float	GetScreenHeight ( void ) const	{	return m_fScreenHeight;	} 

	ObjectManager* GetObjectManager()const { return m_pObjectManager; }
	//float	GetWorldWidth (void)	 const  {return WorldWidth;}
	//float	GetWorldHeight(void)	 const  {return WorldHeight;}

	int			GetCamX(void)			const	{return CameraPosX;}
	int			GetCamY(void)			const	{return CameraPosY;}
	float		GetWorldTimer(void)		const	{return m_fWorldTimer; }
	float       GetTrackTimer(void)     const	{return m_fTrackTimer;}
	bool		GetVictory(void)		const	{return m_bVictory;}
	SGD::Point	GetPlayerPos()			const;
	SGD::Point	GetPlayerStart()		const	{ return m_ptPlayerPosition; }
	
	
	void	SetCameraX(int n)		{ CameraPosX = n; }
	void	SetCameraY(int n)		{ CameraPosY = n; }
	void	SetIsActiveTimer(bool b){ m_bTimer = b;	  }
	void	SetPortal(unsigned char portal)	{ m_cPortal = portal; }
	void	SetPlayerStart(SGD::Point pt)	{ m_ptPlayerPosition = pt; }

	// Pause Menu
	void	Pause();
	bool	PauseInput(SGD::InputManager*);
	void	Save();

	/*******************************************************************/
	void		SetWorldTimer(float time )		{ m_fWorldTimer = time; }
	void		SetVictory(bool victory)		{m_bVictory = victory;}

	/**********************************************************/
	// IGameState Interface:
	virtual void	Enter	( void )				override;	// load resources
	virtual void	Exit	( void )				override;	// unload resources
													
	virtual bool	Input	( void )				override;	// handle user input
	virtual void	Update	( float elapsedTime )	override;	// update game entities / animations
	virtual void	Render	( void )				override;	// render game entities / menus


	//Helper Functions
	Player*		CreatePlayer(void) const;
	void		CreateGrappleGun(void) const;
	void		CreateGrappleHook(void) const;
	Crosshair*	CreateCrosshair(void);
	

private:
	/**********************************************************/
	// SINGLETON (not-dynamically allocated)
	GameplayState( void )			= default;	// default constructor
	virtual ~GameplayState( void )	= default;	// destructor

	GameplayState( const GameplayState& )				= delete;	// copy constructor
	GameplayState& operator= ( const GameplayState& )	= delete;	// assignment operator

	// Pause menu
	bool							m_bPause;
	std::vector<SGD::String>		m_szItems;
	std::map<int, SGD::String>		m_mSelectedItem;
	unsigned int					m_nNumItems;
	int								m_nPauseCursor = 0;
	float							m_fControlTimer;
	bool							m_bSave = false;

	//TileSystem
	//TileSystem* m_tTile;
	/**********************************************************/
	// Screen Size
	float					m_fScreenWidth	= 1;
	float					m_fScreenHeight = 1;

	int  CameraPosX;
	int  CameraPosY;
	//*******************************************************************
	// Assets

	// Image Handlers
	SGD::HTexture		m_hBackgroundImage		= SGD::INVALID_HANDLE;
	SGD::HTexture		m_hPlayer				= SGD::INVALID_HANDLE;
	SGD::HTexture		m_hPotion				= SGD::INVALID_HANDLE;
	SGD::HTexture		m_hCrosshair			= SGD::INVALID_HANDLE;
	SGD::HTexture		m_hFrame				= SGD::INVALID_HANDLE;
	// Audio Handlers
	SGD::HAudio			m_hBackgroundMusic		= SGD::INVALID_HANDLE;
	

	/**********************************************************/
	// Game Entities
	Player*					m_pPlayer			= nullptr;	
	SGD::Point				m_ptPlayerPosition;
	Explosion*				explosion			= nullptr;
	Crosshair*				m_pCrosshair		= nullptr;
	ObjectManager *			m_pObjectManager;
	Camera*					m_pCamera;
	Bomb*					m_pBomb;
//	Crate*					m_pCrate			= nullptr;
	/**********************************************************/
	// Event & Message Managers
	SGD::EventManager*		m_pEvents			= nullptr;
	SGD::MessageManager*	m_pMessages			= nullptr;
	
	// Message Callback Function:
	static void MessageProc( const SGD::Message* pMsg );


	/************************************************************/
	float			m_fWorldTimer	=	-1.f;
	float			m_fTrackTimer   =	-1.f;
	bool			m_bExplode		=	false;  // does nothing
	bool			m_bVictory		=	false;
	bool			m_bTimer		=	true;

	BitmapFont*		font;

	enum { PortalMainMenu, PortalNext};
	unsigned char	m_cPortal;
	bool			m_bMainMenu = false;

	bool			m_bInTutorial;
};

#endif //GAMEPLAYSTATE_H
